from heap.slot import Slots


class OperandStack(Slots):

    def __init__(self):
        super().__init__()
        self.size = 0

    @staticmethod
    def newOperandStack(maxStack):
        stack = OperandStack().makeSlot(maxLocals=maxStack)
        stack.size = 0
        return stack

    def pushInt(self, value):
        self.setInt(self.size, value)
        self.size += 1

    def popInt(self):
        self.size -= 1
        self.getInt(self.size)

    def pushFloat(self, value):
        self.setFloat(self.size, value)
        self.size += 1

    def popFloat(self):
        self.size -= 1
        return self.getFloat(self.size)

    def pushLong(self, value):
        self.setLong(self.size, value)
        self.size += 2

    def popLong(self):
        self.size -= 2
        return self.getLong(self.size)

    def pushDouble(self, value):
        self.setDouble(self.size, value)
        self.size += 2

    def popDouble(self):
        self.size -= 2
        return self.getDouble(self.size)

    def pushRef(self, value):
        self.setRef(self.size, value)
        self.size += 1

    def popRef(self):
        self.size -= 1
        return self.getRef(self.size)

    def pushBoolean(self, value: bool):
        if value:
            self.setInt(self.size, 1)
        else:
            self.setInt(self.size, 0)
        self.size += 1

    def popBoolean(self):
        self.size -= 1
        return self.getInt(self.size) == 1

    def popSlot(self):
        self.size -= 1
        return self.getSlot(self.size)

    def pushSlot(self, v):
        self.setSlot(self.size, v)
        self.size += 1

    def getRefFromTop(self, index):
        return self.getRef(self.size - index - 1)


